package operation;

import abbot.WaitTimedOutException;
import abbot.finder.BasicFinder;
import abbot.finder.ComponentNotFoundException;
import abbot.finder.MultipleComponentsFoundException;
import abbot.finder.matchers.WindowMatcher;
import abbot.tester.ActionFailedException;
import abbot.tester.Robot;
import abbot.util.Condition;
import com.supermap.data.Dataset;
import com.supermap.data.Datasource;
import com.supermap.data.DatasourceConnectionInfo;
import com.supermap.data.EngineType;
import com.supermap.desktop.controls.ui.MainFrame;
import com.supermap.desktop.core.Application;
import compareResult.datasetCompare.DatasetComparer;
import robotCross.TipMatcher;
import util.Info;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.util.concurrent.TimeoutException;

import static socketEnv.DataUtil.ensureReachable;

/**
 * Created by hanyz on 2017/1/13.
 */
public class CommonOperation {

	//================== 数据源 =====================

	/**
	 * 新建文件型数据源，已存在时覆盖。
	 *
	 * @param filePath
	 * @param makeDir
	 */
	public static void createUDB(String filePath, boolean makeDir) throws Exception {
		new WorkspaceTreeOperation().selectTheDatasouceNodeMenu("新建文件型数据源...");
		Operation.robot.delay(1000);
		new JFileChooserOperation().createFile(filePath, makeDir);
	}

	public static void createUDB(String filePath) throws Exception {
		createUDB(filePath, true);
	}


	public static void openUDB(String filePath, boolean readOnly) throws Exception {
		new WorkspaceTreeOperation().selectTheDatasouceNodeMenu("打开文件型数据源...");
		Operation.robot.delay(1000);
		new JFileChooserOperation().chooseFile(filePath, readOnly);
	}

	public static void openUDB(String filePath) throws Exception {
		openUDB(filePath, false);
	}

	public void openSMWU(String filePath) throws Exception {
		ensureReachable();
		new WorkspaceTreeOperation().selectWorkspaceNodeMenu("打开文件型工作空间...");
		new CommonOperation().waitForJFileChooserDisplay(60000);
		new JFileChooserOperation().chooseFile(filePath);
	}

	/**
	 * 新建数据源，不通过桌面执行。需要桌面执行新建数据源的用例可以单独再写。
	 *
	 * @param DsPath
	 * @param makeDir
	 * @return
	 */
	public static boolean createDatasource(String DsPath, boolean makeDir) {
		File file = new File(DsPath);
		String path = file.getParent();
		File dir = new File(path);
		if (!dir.exists()) {
			if (makeDir) {
				dir.mkdirs();
				if (!dir.exists()) {
					Info.out("目录创建失败：" + dir);
					return false;
				}
			} else {
				Info.out("目录不存在，且未设置创建目录：" + dir);
				return false;
			}
		}
		DatasourceConnectionInfo info = new
				DatasourceConnectionInfo();
		info.setServer(DsPath);
		return new Datasource(EngineType.UDB).create(info);
	}

	/**
	 * 新建数据源，目录不存在时新建目录
	 *
	 * @return
	 */
	public static boolean createDatasource(String DsPath) {
		return createDatasource(DsPath, true);
	}

	/**
	 * 获取工作空间中的数据源
	 *
	 * @param item
	 * @return
	 */
	public static Datasource getDatasource(Object item) {
		if (item instanceof String) {
			return Application.getActiveApplication().getWorkspace().getDatasources().get((String) item);
		} else if (item instanceof Integer) {
			return Application.getActiveApplication().getWorkspace().getDatasources().get((Integer) item);
		}
		return null;
	}

	/**
	 * 打开文件型数据源，不经过桌面
	 *
	 * @param path
	 * @return
	 */
	public static Datasource openDatasource(String path) throws Exception {
		DatasourceConnectionInfo info = new
				DatasourceConnectionInfo();
		info.setServer(path);
		info.setReadOnly(true);
		Datasource datasource = new Datasource(EngineType.UDB);
		datasource.open(info);
		//用这种方式打开的数据源记录到list中，在test执行结束后调用释放
		if (datasource.isConnected()) {
			if (!Operation.datasources.contains(datasource)) {
				Operation.datasources.add(datasource);
			}
			return datasource;
		}
		throw new Exception("Fail to open Datasource:" + path);
	}


	/**
	 * @param datasourceName 数据源名称
	 * @param datasetNames  要删除的数据集名称，多个数据集名称以|区分
	 * Author:caolp
	 */
	public void deleteDatasets(String datasourceName, String datasetNames) throws Exception {
		new WorkspaceTreeOperation().selectDatasetNodeMenu(datasourceName,datasetNames,"删除数据集");
		Operation.robot.delay(2000);
		new DialogOperation().clickComponent(new TipMatcher("确定"));
		Operation.robot.delay(6000);
		System.out.println("delet dataset finished!");
		//waitForWindowDispose(CrossProperties.getProperty(CrossProperties.PropertiesEnum.Core, "String_MessageBox_Title"),8000);
	}

	public void waitForWindowDispose(final String title, int timeout) {
		Condition cond = new Condition() {
			@Override
			public boolean test() {
				Component component = null;
				try {
					component = new BasicFinder().find(new WindowMatcher(title));
				} catch (ComponentNotFoundException e) {
//					e.printStackTrace();
				} catch (MultipleComponentsFoundException e) {
//					e.printStackTrace();
				}
				if (component == null || !component.isVisible()) {
					return true;
				}
				return false;
			}
		};
		try {
			Robot.wait(cond, timeout);
		} catch (WaitTimedOutException wto) {
			throw wto;
		}
	}

	public void waitForWindowDispose(final Container container, int timeout) {
		Condition cond = new Condition() {
			@Override
			public boolean test() {
				if (container == null || !container.isVisible()) {
					return true;
				}
				return false;
			}
		};
		try {
			Robot.wait(cond, timeout);
		} catch (WaitTimedOutException wto) {
			throw wto;
		}
	}

	/**
	 * 等待进程对话框关闭
	 *
	 * @param timeOut
	 */
	public void waitForProgressDispose(long timeOut) throws TimeoutException {
		long startTime = System.currentTimeMillis();
		if (new DialogOperation().findProgressDialog() == null) {
			return;
		}
		while (new DialogOperation().findProgressDialog() != null) {
			long currentTime = System.currentTimeMillis();
			long totalTime = currentTime - startTime;
			if (totalTime > timeOut) {
				throw new TimeoutException("执行时间总计为:" + totalTime + ",大于最大允许时间，可能是运行环境出问题或是该功能性能降低");
			}
		}
		System.out.println("窗口已释放");
	}
	public JFileChooser waitForJFileChooserDisplay(int timeout) throws Exception {
		ensureReachable();
		Condition cond = new Condition() {
			@Override
			public boolean test() {
				JFileChooser jFileChooser = new JFileChooserOperation().findJFileChooser();
				if (jFileChooser != null) {
					return true;
				}
				return false;
			}
		};
		try {
			Robot.wait(cond, timeout);
		} catch (WaitTimedOutException wto) {
			throw new ActionFailedException("JFileChooser not found!");
		}
		return new JFileChooserOperation().findJFileChooser();
	}
	public JFileChooser waitForJFileChooserDisplay() throws Exception {
		return waitForJFileChooserDisplay(60000);
	}

	public void toFront() {
		MainFrame mainFrame = (MainFrame) Application.getActiveApplication().getMainFrame();
		mainFrame.toFront();
	}
}
